﻿using System;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using DeepEarth.Map.Core;
using DeepEarth.Map.Core.Converters;
using System.Collections.Generic;
using DeepEarth.Map.Core.Utilities;
using System.Windows.Input;
using DeepEarth.Core;
using DeepEarth.Map.Core.Tiling;

namespace DeepEarth.Map
{
    public partial class Map : Grid, IMap
    {
        #region IMap
        public bool IsWrapped
        {
            get { return false; }
        }

        public FrameworkElement AsFrameworkElement
        {
            get { return this; }
        }

        public Location ViewportPointToLocation(Point point)
        {
            return this.PixelToGeographic(point);
        }

        public Point LocationToViewportPoint(Location location)
        {
            Point p = this.GeographicToPixel(location);
            return p;
        }

        public double ZoomLevel
        {
            get
            {
                return MapView.ZoomLevelFromViewportWidth(this.masterMsi.ActualWidth, this.TargetViewportWidth);
            }
            set
            {
                if (value < 1) value = 1;

                var zoom = Math.Pow(2, value - 1);
                TargetViewportWidth = ZoomToViewportWidth(zoom);
                SyncMapToTarget();
            }
        }

        /// <summary>
        /// Pan the map with deltas in pixels
        /// </summary>
        public void Pan(double deltaX, double deltaY)
        {
            double logicalDeltaX = (deltaX / ActualWidth) * masterMsi.ViewportWidth;
            double logicalDeltaY = (deltaY / ActualHeight) * masterMsi.ViewportWidth;


            targetViewportOrigin = new Point(targetViewportOrigin.X + logicalDeltaX,
                                             targetViewportOrigin.Y + logicalDeltaY);

            SyncMapToTarget();
        }

        public void Zoom(double delta)
        {
            delta = delta > 0 ? 1.3 : 0.7;
            Zoom(delta, masterMsi.ElementToLogicalPoint(new Point(masterMsi.ActualWidth / 2, masterMsi.ActualHeight / 2)));
        }

        public Location CurrentCenter
        {
            get
            {                                         
                Point p = logicalCentre(masterMsi);
                return CoordinateTransformation.LogicalToGeographic(p);
            }
        }

        public double CurrentViewportLogicalWidth
        {
            get
            {
                return masterMsi.ViewportWidth;
            }
        }

        public IMap CreateInstance()
        {
            return new Map();
        }

        public static readonly DependencyProperty ViewProperty = DependencyProperty.Register("View", typeof(MapView), typeof(Map), new PropertyMetadata(ViewPropertyChanged));

        public DependencyProperty ViewDependencyProperty
        {
            get
            {
                return Map.ViewProperty;
            }
        }

        public string ViewDependencyPropertyPath
        {
            get
            {
                return "View";
            }
        }

        public Panel OverlayPanel { get; set; }

        public RasterOverlayCollection BaseRasterOverlayCollection { get; private set; }
        public Canvas BaseDynamicLayer { get; private set; }
        public VectorLayerCollection BaseVectorLayerCollection { get; private set; }
        public Canvas BaseLabelLayer { get; private set; }

        public Panel InteractionSurface { get; set; }

        public UIElementCollection BaseChildren
        {
            get
            {
                return base.Children;
            }
        }

        public BaseTileSourceProvider TileSourceProvider
        {
            get { return (BaseTileSourceProvider)GetValue(TileSourceProviderProperty); }
            set { SetValue(TileSourceProviderProperty, value); }
        }

        public static readonly DependencyProperty TileSourceProviderProperty =
            DependencyProperty.Register("TileSourceProvider", typeof(BaseTileSourceProvider), typeof(Map), new PropertyMetadata(TileSourceProviderPropertyChanged));

        private static void TileSourceProviderPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
        {
            Map self = sender as Map;

            if (args.NewValue != null && self.View != null)
            {
                self.View.TileSourceProvider = args.NewValue as BaseTileSourceProvider;
            }
        }

        bool disableZoom = false;
        public bool DisableZoom
        {
            get
            {
                return disableZoom;
            }
            set
            {
                disableZoom = value;
            }
        }

        public AnimationLevel AnimationLevel
        {
            get { return AnimationLevel.Full; }
            set
            {

            }
        }


        #endregion

    }
}
